package gamethreads;

import gameobjects.*;

import java.util.ArrayList;
import javagame.Level;
import org.newdawn.slick.Animation;
import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;

public class ProtivnikT extends Thread {

	//NABROJIVI TIPOVI
	
	public enum tip_protivnika {SIVI, CRNI, TOP};
	
	//KONSTANTE
	
	private int[] duration = {200, 200};
	private static int maxBrTop = 30;//maksimalan broj topova koji se mogu nalaziti na protivniku
	
	//POLJA KLASE
	
	private tip_protivnika vrsta;//vrsta protivnika
	private int HP;//snaga protivnika "helth"
	private Level nivo;
	private Animation eksplozija;
	private float protivnikX;//x pozicija protivnika
	private float protivnikY;//y pozicija protivnika
	private int smer;//smer kretanja
	private boolean ubiven;//da li je protivnik mrtav ili ne;
	private Animation protivnik;//animacija koja je trenutno aktivna
	private Animation movingUp;//animacija za kretanje na gore
	private Animation movingDown;//animacija za kretanje na dole
	private Animation movingLeft;//animacija za kretanje na levo
	private Animation movingRight;//animacija za kretanje na desno
	private int smerOdbrojavanje;//koliko moze da se krece protivnik
	private int metakOdbrojavanje;
	private Igrac igrac;//protivnik mora da bude svestan postojanja igraca
	private Igrac2 igrac2;////protivnik mora da bude svestan postojanja igraca
	private boolean imaDvaIgraca;
	private ArrayList<Metak> meci;//lista metaka koje protivnik ispaljuje
	private int sizeX;//velicina protivnika po x osi
	private int sizeY;//velicina protivnika po x osi
	private int zid;//velicina zida koju protivnik moze da pregazi
	private int zid2;//velicina zida koju protibnik moze da pregazi
	private int brojTopova;//koliko topova ima protivnik
	private KoordinateTopova[] kordTop;//koordinate topova iz kojih se puca	
	private int tenkPomeraj;//kada da protivnik puca na igraca
	private int protivnikPomerajX;//kada da protivnik puca po x
	private int protivnikPomerajY;//kada da protivnik puca po y	
	private boolean shooting;//indikator da li protivnik puca
	private boolean stop;//da li da protivnik stane dok puca
	private boolean shooting2;//indikator da li protivnik puca na drugog igraca
	private boolean stop2;//da li da protivnik stane dok puca na drugog igraca
	private String ime;//ime protivnika
	private int delta;//delta
	private Kolizija kolizija;//kolizija
	private boolean belo;//koje su boje meci
	private Barijera barijera;//barijera na kojoj se blokiraju niti

	//KONSTRUKTOR

	public ProtivnikT(Igrac igrac, Igrac2 igrac2, Level nivo, String ime, Kolizija kolizija, boolean belo){
		meci = new ArrayList<Metak>();
		this.nivo = nivo;
		this.igrac = igrac;
		this.igrac2 = igrac2;
		smerOdbrojavanje = 500;
		metakOdbrojavanje = 1;
		protivnikX = 320;
		protivnikY = 160;
		smer = 0;
		ubiven = false;
		zid = 50;
		zid2 = 0;
		kordTop = new KoordinateTopova[maxBrTop];
		tenkPomeraj = 20;
		protivnikPomerajX = 0;
		protivnikPomerajY = 0;
		shooting = false;
		stop = false;
		shooting2 = false;
		stop2 = false;
		smer = 0;
		this.ime = ime;
		this.kolizija = kolizija;
		this.belo = belo;
		delta = 25;
	}
	
	//GET I SET METODE
	
	public float getProtivnikX() {
		return protivnikX;
	}
	
	public void setDelta(int delta) {
		this.delta = delta;
	}

	public int getDelta() {
		return delta;
	}

	public void setProtivnikX(float protivnikX) {
		this.protivnikX = protivnikX;
	}
	
	public float getProtivnikY() {
		return protivnikY;
	}
	
	public void setProtivnikY(float protivnikY) {
		this.protivnikY = protivnikY;
	}
	
	public int getSmer() {
		return smer;
	}
	
	public void setSmer(int smer) {
		this.smer = smer;
	}
	
	public Animation getEksplozija() {
		return eksplozija;
	}

	public void setEksplozija(Animation eksplozija) {
		this.eksplozija = eksplozija;
	}

	public boolean isUbiven() {
		return ubiven;
	}

	public void setUbiven(boolean ubiven) {
		this.ubiven = ubiven;
	}

	public ArrayList<Metak> getMeci() {
		return meci;
	}

	public void setMeci(ArrayList<Metak> meci) {
		this.meci = meci;
	}
	
	public tip_protivnika getVrsta() {
		return vrsta;
	}

	public void setVrsta(tip_protivnika vrsta) {
		this.vrsta = vrsta;
	}

	public Level getNivo() {
		return nivo;
	}

	public void setNivo(Level nivo) {
		this.nivo = nivo;
	}

	public Animation getProtivnik() {
		return protivnik;
	}

	public void setProtivnik(Animation protivnik) {
		this.protivnik = protivnik;
	}

	public Animation getMovingUp() {
		return movingUp;
	}

	public void setMovingUp(Animation movingUp) {
		this.movingUp = movingUp;
	}

	public Animation getMovingDown() {
		return movingDown;
	}

	public void setMovingDown(Animation movingDown) {
		this.movingDown = movingDown;
	}

	public Animation getMovingLeft() {
		return movingLeft;
	}

	public void setMovingLeft(Animation movingLeft) {
		this.movingLeft = movingLeft;
	}

	public Animation getMovingRight() {
		return movingRight;
	}

	public void setMovingRight(Animation movingRight) {
		this.movingRight = movingRight;
	}

	public int getHP() {
		return HP;
	}

	public void setHP(int hP) {
		HP = hP;
	}

	public int getSmerOdbrojavanje() {
		return smerOdbrojavanje;
	}

	public void setSmerOdbrojavanje(int smerOdbrojavanje) {
		this.smerOdbrojavanje = smerOdbrojavanje;
	}

	public int getMetakOdbrojavanje() {
		return metakOdbrojavanje;
	}

	public void setMetakOdbrojavanje(int metakOdbrojavanje) {
		this.metakOdbrojavanje = metakOdbrojavanje;
	}
	
	public int incSmerO() {
		return smerOdbrojavanje--;
	}
	
	public int incMetakO() {
		return metakOdbrojavanje--;
	}
	
	public int[] getDuration() {
		return duration;
	}
	
	public Igrac getIgrac() {
		return igrac;
	}

	public void setIgrac(Igrac igrac) {
		this.igrac = igrac;
	}

	public void setDuration(int[] duration) {
		this.duration = duration;
	}

	public int getSizeX() {
		return sizeX;
	}

	public void setSizeX(int sizeX) {
		this.sizeX = sizeX;
	}

	public int getSizeY() {
		return sizeY;
	}

	public void setSizeY(int sizeY) {
		this.sizeY = sizeY;
	}
	
	public int getZid() {
		return zid;
	}

	public void setZid(int zid) {
		this.zid = zid;
	}

	public int getBrojTopova() {
		return brojTopova;
	}

	public void setBrojTopova(int brojTopova) {
		this.brojTopova = brojTopova;
	}

	public KoordinateTopova[] getKordTop() {
		return kordTop;
	}

	public void setKordTop(KoordinateTopova[] kordTop) {
		this.kordTop = kordTop;
	}
	
	public KoordinateTopova getKordTop(int index) {
		return kordTop[index];
	}

	public int getTenkPomeraj() {
		return tenkPomeraj;
	}

	public void setTenkPomeraj(int tenkPomeraj) {
		this.tenkPomeraj = tenkPomeraj;
	}

	public int getProtivnikPomerajX() {
		return protivnikPomerajX;
	}

	public void setProtivnikPomerajX(int protivnikPomerajX) {
		this.protivnikPomerajX = protivnikPomerajX;
	}
	
	public int getProtivnikPomerajY() {
		return protivnikPomerajY;
	}

	public void setProtivnikPomerajY(int protivnikPomerajY) {
		this.protivnikPomerajY = protivnikPomerajY;
	}
	
	public boolean isShooting() {
		return shooting;
	}

	public void setShooting(boolean shooting) {
		this.shooting = shooting;
	}

	public boolean isStop() {
		return stop;
	}

	public void setStop(boolean stop) {
		this.stop = stop;
	}
	
	public Igrac2 getIgrac2() {
		return igrac2;
	}

	public void setIgrac2(Igrac2 igrac2) {
		this.igrac2 = igrac2;
	}

	public boolean isImaDvaIgraca() {
		return imaDvaIgraca;
	}

	public void setImaDvaIgraca(boolean imaDvaIgraca) {
		this.imaDvaIgraca = imaDvaIgraca;
	}

	public boolean isShooting2() {
		return shooting2;
	}

	public void setShooting2(boolean shooting2) {
		this.shooting2 = shooting2;
	}

	public void setBarijera(Barijera barijera) {
		this.barijera = barijera;
	}

	public Barijera getBarijera() {
		return barijera;
	}

	public boolean isStop2() {
		return stop2;
	}

	public void setStop2(boolean stop2) {
		this.stop2 = stop2;
	}
	
	public int getZid2() {
		return zid2;
	}

	public void setZid2(int zid2) {
		this.zid2 = zid2;
	}
	
	public void setIme(String ime) {
		this.ime = ime;
	}

	public String getIme() {
		return ime;
	}
		
	//PUCANJE
	
	public void setKolizija(Kolizija kolizija) {
		this.kolizija = kolizija;
	}

	public Kolizija getKolizija() {
		return kolizija;
	}

	//kreira i dodaje metak za pucanje u jednom smeru
	public void pucaj(float x, float y, int smerM) throws SlickException {
		Metak m=new Metak();
		if (belo) m.setBoja(Color.white);
		else m.setBoja(Color.black);
		m.setMetakX(x);
		m.setMetakY(y);	
		m.setSmer(smerM);
		meci.add(m);
		//pucanj.play();
	}
	
	//pucanje puca na igraca zavisno od smera
	public void pucanje() throws SlickException {
		for(int i=0;i<brojTopova;i++) {
			//smer kretanja metka
			//levo
			if(smer == 3) pucaj(protivnikX + kordTop[i].getSmer3X(), protivnikY + kordTop[i].getSmer3Y(), smer);
			//desno
			if(smer == 2) pucaj(protivnikX + kordTop[i].getSmer2X(), protivnikY + kordTop[i].getSmer2Y(), smer);
			//gore
			if(smer == 1) pucaj(protivnikX + kordTop[i].getSmer1X(), protivnikY + kordTop[i].getSmer1Y(), smer);
			//dole
			if(smer == 0) pucaj(protivnikX + kordTop[i].getSmer0X(), protivnikY + kordTop[i].getSmer0Y(), smer);
		}
	}
	
	//sta treba uraditi kada se puca
	public void firing(int smer) throws SlickException {
		metakOdbrojavanje--;
		if(metakOdbrojavanje == 0) {
			setSmer(smer);
			promeniAnimaciju();
			pucanje();
			metakOdbrojavanje = 10;
		}
	}
	
	//kada se uoci igraca, puca se na njega
	public void fire() throws SlickException {
		//igrac se nalazi gore
		if(igrac.isZiv()
				&& protivnikX <= igrac.getTenkX() + tenkPomeraj 
				&& protivnikX + protivnikPomerajX >= igrac.getTenkX() - tenkPomeraj 
				&& protivnikY <= igrac.getTenkY()) {
			shooting = true;
			firing(0);
		}
		//igrac se nalazi dole
		else if(igrac.isZiv()
				&& protivnikX <= igrac.getTenkX() + tenkPomeraj 
				&& protivnikX + protivnikPomerajX >= igrac.getTenkX() - tenkPomeraj 
				&& protivnikY > igrac.getTenkY()) {
			shooting = true;
			firing(1);
		}
		//igrac se nalazi levo
		else if(igrac.isZiv()
				&& protivnikY <= igrac.getTenkY() + tenkPomeraj 
				&& protivnikY + protivnikPomerajY >= igrac.getTenkY() - tenkPomeraj 
				&& protivnikX <= igrac.getTenkX()) {
			shooting = true;
			firing(2);
		}
		//igrac se nalazi desno
		else if(igrac.isZiv()
				&& protivnikY <= igrac.getTenkY() + tenkPomeraj 
				&& protivnikY + protivnikPomerajY >= igrac.getTenkY() - tenkPomeraj 
				&& protivnikX > igrac.getTenkX()) {
			shooting = true;
			firing(3);
		}
		else {
			shooting = false;
			stop = false;
		}
		if(imaDvaIgraca) {
			//igrac2 se nalazi gore
			if(igrac2.isZiv() 
					&& protivnikX <= igrac2.getTenkX() + tenkPomeraj 
					&& protivnikX + protivnikPomerajX >= igrac2.getTenkX() - tenkPomeraj 
					&& protivnikY <= igrac2.getTenkY()) {
				shooting2 = true;
				firing(0);
			}
			//igrac2 se nalazi dole
			else if(igrac2.isZiv() 
					&& protivnikX <= igrac2.getTenkX() + tenkPomeraj 
					&& protivnikX + protivnikPomerajX >= igrac2.getTenkX() - tenkPomeraj 
					&& protivnikY > igrac2.getTenkY()) {
				shooting2 = true;
				firing(1);
			}
			//igrac2 se nalazi levo
			else if(igrac2.isZiv() 
					&&protivnikY <= igrac2.getTenkY() + tenkPomeraj 
					&& protivnikY + protivnikPomerajY >= igrac2.getTenkY() - tenkPomeraj 
					&& protivnikX <= igrac2.getTenkX()) {
				shooting2 = true;
				firing(2);
			}
			//igrac2 se nalazi desno
			else if(igrac2.isZiv() 
					&& protivnikY <= igrac2.getTenkY() + tenkPomeraj 
					&& protivnikY + protivnikPomerajY >= igrac2.getTenkY() - tenkPomeraj 
					&& protivnikX > igrac2.getTenkX()) {
				shooting2 = true;
				firing(3);
			}
			else {
				shooting2 = false;
				stop2 = false;
			}
		}
	}
	
	//KRETANJE
	
	//kretanje, kada ovo ne bi postojalo protivnici bi stajali
	public void kreciSe() { //kada da se protivnik krece
		if(protivnikX < 1024 && protivnikX > 0 && stop == false && stop2 == false) {
			if(smer == 3) protivnikX -= delta * .1f;
			else if(smer == 2) protivnikX += delta * .1f;
			else if(smer == 1) protivnikY -= delta * .1f;
			else if(smer == 0) protivnikY += delta * .1f;
		}
	}
		
	//ako se udari u kraj nivoa
	public void promenaSmeraKrajNivoa() {
		if(protivnikX >= 1024 - sizeX) {
			smer=3;
			promeniAnimaciju();
			protivnikX -= delta * .1f;
		}
		else if(protivnikX <= zid2) {
			smer=2;
			promeniAnimaciju();
			protivnikX+= delta * .1f;
		}
		if(protivnikY >= 768 - sizeY) {
			smer=1;
			promeniAnimaciju();
			protivnikY -= delta * .1f;
		}
		else if(protivnikY <= zid) {
			smer=0;
			promeniAnimaciju();
			protivnikY+= delta * .1f;
		}
	}
	
	//promena smera kretanja
	public void promeniSmer() {
		if (shooting == true) {
			if(stop == false) {
				if(smer == 0) protivnikY -= delta * .1f;
				if(smer == 1) protivnikY += delta * .1f;
				if(smer == 2) protivnikX -= delta * .1f;
				if(smer == 3) protivnikX += delta * .1f;
			}
			stop = true;
		}
		else if (shooting2 == true) {
			if(stop2 == false) {
				if(smer == 0) protivnikY -= delta * .1f;
				if(smer == 1) protivnikY += delta * .1f;
				if(smer == 2) protivnikX -= delta * .1f;
				if(smer == 3) protivnikX += delta * .1f;
			}
			stop2 = true;
		}
		else 
			if(smer == 2)	{
				smer = 3;
				promeniAnimaciju();
				protivnikX -= delta * .1f;
			}
			else if(smer == 3) {
				smer = 2;
				promeniAnimaciju();
				protivnikX += delta * .1f;
			}
			else if(smer == 1) {
				smer = 0;
				promeniAnimaciju();
				protivnikY += delta * .1f;
			}
			else if(smer == 0) {
				smer = 1;
				promeniAnimaciju();
				protivnikY -= delta * .1f;
			}
		}
	
	public int odrediSmer() {;
		int smer = 0;
		smer = ((int)(Math.random()*3));
		return smer;
	}
	
	//algoritam po kome se menja smer kretanja nakon nekog vremena
	public void algoritamKretanja() {
		//koliko dugo da se krece u jednom smeru
		smerOdbrojavanje--;
		//kada se dodje do kraja promeni se smer
		if(smerOdbrojavanje == 0) {
			smer = odrediSmer();
			smerOdbrojavanje = 200;
			promeniAnimaciju();
		}
	}
		
	//CRTANJE
	
	//crtanje eksplozije
	public void eksplodiraj () {
		eksplozija.draw(protivnikX, protivnikY);
		eksplozija.setLooping(false);
	}
	
	//crtanje protivnika
	public void crtaj(Graphics g) throws SlickException {
		protivnik.draw(protivnikX, protivnikY);
	}
	
	//promena animacje
	public void promeniAnimaciju () {
		if (smer == 0) protivnik = movingDown;
		if (smer == 1) protivnik = movingUp;
		if (smer == 2) protivnik = movingRight;
		if (smer == 3) protivnik = movingLeft;
	}
	
	//OSTALE METODE
	
	//ozivljavanje protivnika, treba kada se pogine pa se nastavlja igra
	public void ozivi() {
		ubiven = false;
		smer = 0;
		setProtivnik(movingDown);
		smerOdbrojavanje = 500;
		metakOdbrojavanje = 1;
		meci.clear();
		eksplozija.setLooping(true);
		eksplozija.restart();
		shooting = false;
		shooting2 = false;
		stop = false;
		stop2 = false;
	}
	
	//dodavanje topa iz kojeg se puca u niz topova
	public void dodajTop(int index, int smer0X, int smer0Y, int smer1X, int smer1Y, 
			int smer2X, int smer2Y, int smer3X, int smer3Y) {
		kordTop[index] = new KoordinateTopova(smer0X, smer0Y, smer1X, smer1Y, smer2X, smer2Y, smer3X, smer3Y);
	}
	
	public void run() {
		while (true)
			try {
				barijera.cekaj();//sinhronizacija na barijeri
				if (!ubiven) {
					protivnikAI();
				}
			} 
			catch (Exception e) {
				e.printStackTrace();
			}
	}
	
	//APSTRAKTNE METODE
	
	//postavljanje animacije
	public void setAnimation() throws SlickException {}
	
	//kretanje
	public void move() {}
	
	//AI protivnika
	public void protivnikAI() throws SlickException {}
	
}
